package services

import (
	"errors"
	"fmt"

	"game-simple/internal/framework/auth/dto"
	"game-simple/internal/framework/auth/models"
	"game-simple/internal/infrastructure/core"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

type UserService struct{}

func NewUserService() *UserService {
	return &UserService{}
}

func (s *UserService) Create(req *dto.UserCreateRequest) (*dto.UserResponse, error) {
	infra := core.Get()

	// 检查用户名是否存在
	var existingUser models.UserModel
	if err := infra.DB.Where("username = ? OR email = ?", req.Username, req.Email).First(&existingUser).Error; err == nil {
		if existingUser.Username == req.Username {
			return nil, errors.New("用户名已存在")
		}
		if existingUser.Email == req.Email {
			return nil, errors.New("邮箱已存在")
		}
	}

	// 加密密码
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
	if err != nil {
		return nil, fmt.Errorf("密码加密失败: %w", err)
	}

	// 创建用户
	user := models.UserModel{
		Username: req.Username,
		Email:    req.Email,
		Password: string(hashedPassword),
	}

	if err := infra.DB.Create(&user).Error; err != nil {
		return nil, fmt.Errorf("创建用户失败: %w", err)
	}

	resp := user.ToUserResponse()
	return &resp, nil
}

func (s *UserService) GetByID(id uint) (*dto.UserResponse, error) {
	infra := core.Get()

	var user models.UserModel
	if err := infra.DB.First(&user, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("用户不存在")
		}
		return nil, fmt.Errorf("查询用户失败: %w", err)
	}

	resp := user.ToUserResponse()
	return &resp, nil
}

func (s *UserService) Update(id uint, req *dto.UserUpdateRequest) (*dto.UserResponse, error) {
	infra := core.Get()

	var user models.UserModel
	if err := infra.DB.First(&user, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("用户不存在")
		}
		return nil, fmt.Errorf("查询用户失败: %w", err)
	}

	// 更新字段
	if req.Username != "" {
		user.Username = req.Username
	}
	if req.Email != "" {
		user.Email = req.Email
	}

	if err := infra.DB.Save(&user).Error; err != nil {
		return nil, fmt.Errorf("更新用户失败: %w", err)
	}

	resp := user.ToUserResponse()
	return &resp, nil
}

func (s *UserService) Delete(id uint) error {
	infra := core.Get()

	if err := infra.DB.Delete(&models.UserModel{}, id).Error; err != nil {
		return fmt.Errorf("删除用户失败: %w", err)
	}
	return nil
}

